package com.swifthealth.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.export.ooxml.JRXlsxExporter;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.export.Exporter;
import net.sf.jasperreports.export.SimpleExporterInput;
import net.sf.jasperreports.export.SimpleOutputStreamExporterOutput;
import net.sf.jasperreports.export.SimpleXlsxReportConfiguration;
import org.apache.commons.io.IOUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

/**
 * Report demo Controller
 *
 * @author houxiurong
 * @date 2021-03-16
 */
@Slf4j
@Api(tags = "jasper报表")
@RestController
@RequestMapping("/report")
public class ReportController {

    private static final String FILE_PATH = "/home/opt/reports/";
    @Resource
    private DataSource dataSource;

    @ApiOperation(value = "upload", notes = "文件上传", httpMethod = "POST")
    @PostMapping("/upload")
    public String uploadReport(@RequestParam(value = "file", required = false) MultipartFile file) {
        if (file.isEmpty()) {
            return "上传失败，请选择文件";
        }
        String filename = file.getOriginalFilename();
        File dest = new File(FILE_PATH + filename);
        try {
            file.transferTo(dest);
            log.info("上传成功");
            return "upload success";
        } catch (IOException e) {
            e.printStackTrace();
            return "upload failed";
        }
    }

    @ApiOperation(value = "export", notes = "导出报表", httpMethod = "GET")
    @GetMapping("/export")
    public void exportExcelSwiftIncome(HttpServletResponse response) throws Exception {
        Class.forName("org.postgresql.Driver");
        Connection connection = DriverManager.getConnection("jdbc:postgresql://192.168.1.100:5432/air_cloud_test", "sys", "sys");
        String jrXmlPath = FILE_PATH + "swiftincome.jrxml";
        String jasperPath = FILE_PATH + "swiftincome.jasper";
        JasperCompileManager.compileReportToFile(jrXmlPath, jasperPath);

        Map parameters = new HashMap();
        parameters.put("whereSql", "");
        //parameters.put("whereSql", " AND statistics in ('2020-01', '2020-02','2020-03','2020-04', '2020-05','2020-06','2020-07', '2020-08','2020-09','2020-10', '2020-11','2020-12') ");
        JasperPrint jasperPrint = JasperFillManager.fillReport(jasperPath, parameters, connection);

        SimpleXlsxReportConfiguration configuration = new SimpleXlsxReportConfiguration();
        String[] sheetName = {"朔维收益统计"};
        configuration.setSheetNames(sheetName);
        configuration.setOnePagePerSheet(true);
        configuration.setIgnoreGraphics(false);
        configuration.setIgnoreCellBorder(false);
        String excelPath = FILE_PATH + "swiftincome.xls";
        File outputFile = new File(excelPath);
        try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
             OutputStream fileOutputStream = new FileOutputStream(outputFile)) {
            Exporter exporter = new JRXlsxExporter();
            exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
            exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(byteArrayOutputStream));
            exporter.setConfiguration(configuration);
            exporter.exportReport();
            byteArrayOutputStream.writeTo(fileOutputStream);
        } catch (Exception e) {
            log.error("报表导出Excel失败", e.getMessage());
        }

        try (OutputStream os = response.getOutputStream();
             InputStream stream = new FileInputStream(excelPath)) {
            response.setContentType("APPLICATION/DOWNLOAD");
            response.setHeader("Content-Disposition", "attachment; filename=" + java.net.URLEncoder.encode("swiftincome.xls", "UTF-8"));
            response.setContentLength(stream.available());
            int iBytesRead;
            byte[] buffer = new byte[10240000];
            while ((iBytesRead = stream.read(buffer, 0, 10240000)) != -1) {
                os.write(buffer, 0, iBytesRead);
            }
            response.flushBuffer();
        } catch (Exception e) {
            throw e;
        }
    }

    /**
     * 转换为pdf展示
     *
     * @param reportName
     * @param parameters
     * @param response
     * @throws SQLException
     * @throws ClassNotFoundException
     * @throws JRException
     * @throws IOException
     */
    @GetMapping("/report/{reportName}")
    public void getReportByParam(@PathVariable("reportName") final String reportName,
                                 @RequestParam(required = false) Map<String, Object> parameters,
                                 HttpServletResponse response) throws SQLException, ClassNotFoundException, JRException, IOException {
        log.info("reportName={},parameters={}", reportName, parameters);
        parameters = parameters == null ? new HashMap<>() : parameters;
        //获取文件流
        ClassPathResource resource = new ClassPathResource("jaspers" + File.separator + reportName + ".jasper");
        InputStream jasperStream = resource.getInputStream();

        JasperReport jasperReport = (JasperReport) JRLoader.loadObject(jasperStream);
        JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, dataSource.getConnection());
        response.setContentType("application/pdf");
        response.setHeader("Content-Disposition", "inline;");
        final OutputStream outputStream = response.getOutputStream();
        JasperExportManager.exportReportToPdfStream(jasperPrint, outputStream);
        IOUtils.closeQuietly(jasperStream);
        IOUtils.closeQuietly(outputStream);
    }
}
